package org.yxt.message.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 客户端数据处理
 *
 * @author helloword
 * <p>
 * Sep 22, 2017
 */
public class NettyClientSimpleHandler extends SimpleChannelInboundHandler<Object> {

    private Logger logger = LoggerFactory.getLogger(NettyClientSimpleHandler.class);

    // 服务器向客户端响应心跳
    private final String PONG = "pong";

    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        String content = (String) msg;
        // if (msg instanceof ByteBuf) {
        // ByteBuf buf = (ByteBuf) msg;
        // content = buf.toString(Charset.forName("UTF-8"));
        // }
        // 接收服务端的pong
        if (PONG.equals(content)) {
            logger.info("开始接收服务器数据 心跳响应 << {}", content);
        } else {
            logger.info("开始读取服务器数据 << {}", content);
        }
    }

    // 数据读取完成之后释放资源 不使用系统自动关闭
    // @Override
    // public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    // ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    // }

    // 服务器-客户端建立连接之后
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelActive();
    }

    // 心跳事件驱动
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        // IdleStateHandler 所产生的 IdleStateEvent 的处理逻辑.
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            switch (e.state()) {
                case READER_IDLE:
                    handleReaderIdle(ctx);
                    break;
                case WRITER_IDLE:
                    handleWriterIdle(ctx);
                    break;
                case ALL_IDLE:
                    handleAllIdle(ctx);
                    break;
                default:
                    break;
            }
        }
    }

    protected void handleReaderIdle(ChannelHandlerContext ctx) {
        sendPingMsg(ctx);
        // logger.info("CLIENT READER_IDLE");
    }

    protected void handleWriterIdle(ChannelHandlerContext ctx) {
        sendPingMsg(ctx);
        // logger.info("CLIENT WRITER_IDLE");
    }

    protected void handleAllIdle(ChannelHandlerContext ctx) {
        sendPingMsg(ctx);
        // logger.info("CLIENT ALL_IDLE");
    }

    // 客户端端发 ping
    protected void sendPingMsg(ChannelHandlerContext ctx) {
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeBytes("ping".concat(NettyClient.DELIMITER_CHART).getBytes());
        ctx.writeAndFlush(buf);
    }

    // 服务器-客户端连接中断
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        // 连接操作
        NettyClient.getInstance().doConnect();
    }

    // 异常捕获
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("异常捕获 {}", cause.getMessage());
        ctx.close();
    }
}
